﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Web.Script.Serialization;
using System.Xml.Linq;
//
using PerceptiveMCAPI.Types.Internal;
//
namespace PerceptiveMCAPI.Types
{
	public class listsOutput : Api_BaseOutput
	{
		public listsResults result { get; set; }
		public listsParms inputParms { get; private set; }
		//
		public listsOutput( listsInput input )
			: base( input )
		{
			inputParms = input.parms;
			result = new listsResults();
		}
		// --------------------------------------------------- tostring
		public override string ToString()
		{
			return string.Format( "apikey: {0}, number of lists: {1}",
				this.inputParms.apikey, result.data.Count );
		}

		#region ================================================================== format setup
		// ---- serial
		internal void Format( string api_Request, string api_Response )
		{
			this.api_Request = api_Request;
			this.api_Response = api_Response;
			// ----------------------------------
			if ( this.api_OutputType == EnumValues.OutputType.JSON )
				outputJSON();
			else if ( this.api_OutputType == EnumValues.OutputType.XML )
				outputXML();
		}
		// ---- xmlrpc
		internal void Format( x_lists rpcResult )
		{
			this.api_Request = EnumValues.NotSupplied;
			this.api_Response = EnumValues.NotSupplied;
			// ------------------------
			this.result = FormatResults( rpcResult );
		}
		#endregion

		#region  ===================================================================== format result
		// ---------------------------------------------------------- outputXML
		protected void outputXML()
		{
			XElement xml = XElement.Parse( this.api_Response );
			// error check
			Api_Error error = apiSerial.GetXmlOutputError( xml );
			if ( error != null )
			{
				this.api_ErrorMessages.Add( error );
				return;
			}
			// -------------------------------------------- get values
			int it; DateTime dt; double dbl;
			try
			{
				int.TryParse( xml.Element( "total" ).Value, out it );
				this.result.total = it;
				//
				if ( xml.Element( "data" ).HasElements )
				{
					IEnumerable<XElement> lists = xml.Element( "data" ).Elements( "struct" );
					foreach ( XElement entry in lists )
					{
						listsResults.DataItem lst = new listsResults.DataItem();
						// ----------------------------------
						lst.id = entry.Element( "id" ).Value;
						int.TryParse( entry.Element( "web_id" ).Value, out it );
						lst.web_id = it;
						lst.name = entry.Element( "name" ).Value;
						DateTime.TryParse( entry.Element( "date_created" ).Value, out dt );
						lst.date_created = dt;
						lst.email_type_option = ( entry.Element( "email_type_option" ).Value.Trim() == "1" ) ? true : false;
						lst.use_awesomebar = ( entry.Element( "use_awesomebar" ).Value.Trim() == "1" ) ? true : false;
						lst.default_from_name = entry.Element( "default_from_name" ).Value;
						lst.default_from_email = entry.Element( "default_from_email" ).Value;
						lst.default_subject = entry.Element( "default_subject" ).Value;
						lst.default_language = entry.Element( "default_language" ).Value;
						double.TryParse( entry.Element( "list_rating" ).Value, out dbl );
						lst.list_rating = dbl;
						// --------------------------
						if ( entry.Element( "stats" ).HasElements )
						{
							XElement stats = entry.Element( "stats" );
							//
							double.TryParse( stats.Element( "member_count" ).Value, out dbl );
							lst.stats.member_count = dbl;
							double.TryParse( stats.Element( "unsubscribe_count" ).Value, out dbl );
							lst.stats.unsubscribe_count = dbl;
							double.TryParse( stats.Element( "cleaned_count" ).Value, out dbl );
							lst.stats.cleaned_count = dbl;
							//
							double.TryParse( stats.Element( "member_count_since_send" ).Value, out dbl );
							lst.stats.member_count_since_send = dbl;
							double.TryParse( stats.Element( "unsubscribe_count_since_send" ).Value, out dbl );
							lst.stats.unsubscribe_count_since_send = dbl;
							double.TryParse( stats.Element( "cleaned_count_since_send" ).Value, out dbl );
							lst.stats.cleaned_count_since_send = dbl;
							//
							double.TryParse( stats.Element( "campaign_count" ).Value, out dbl );
							lst.stats.campaign_count = dbl;
							double.TryParse( stats.Element( "grouping_count" ).Value, out dbl );
							lst.stats.grouping_count = dbl;
							double.TryParse( stats.Element( "group_count" ).Value, out dbl );
							lst.stats.group_count = dbl;
							double.TryParse( stats.Element( "merge_var_count" ).Value, out dbl );
							lst.stats.merge_var_count = dbl;
							double.TryParse( stats.Element( "avg_sub_rate" ).Value, out dbl );
							lst.stats.avg_sub_rate = dbl;
							double.TryParse( stats.Element( "avg_unsub_rate" ).Value, out dbl );
							lst.stats.avg_unsub_rate = dbl;
							double.TryParse( stats.Element( "target_sub_rate" ).Value, out dbl );
							lst.stats.target_sub_rate = dbl;
							double.TryParse( stats.Element( "open_rate" ).Value, out dbl );
							lst.stats.open_rate = dbl;
							double.TryParse( stats.Element( "click_rate" ).Value, out dbl );
							lst.stats.click_rate = dbl;
						}
						//------------------- ??????????? check out
						lst.modules = null;
						//------------------- 
						this.result.data.Add( lst );
					}
				}
			}
			catch ( Exception ex )
			{
				this.api_ErrorMessages.Add( apiException.FormatError( ex ) );
			}
		}
		// ---------------------------------------------------------- outputJSON
		protected void outputJSON()
		{
			JavaScriptSerializer jss = new JavaScriptSerializer();

			try
			{
				if ( this.api_Response.Contains( EnumValues.JSONErrorString ) )
				{
					Api_Error err = jss.Deserialize<Api_Error>( this.api_Response );
					this.api_ErrorMessages.Add( err );
				}
				else
				{
					x_lists jsonResult = jss.Deserialize<x_lists>( this.api_Response );
					this.result = FormatResults( jsonResult );
				}
			}
			catch ( Exception ex )
			{
				this.api_ErrorMessages.Add( apiException.FormatError( ex ) );
			}
		}
		// -----------------------------------------------------
		protected listsResults FormatResults( x_lists x_results )
		{
			listsResults results = new listsResults();
			results.total = x_results.total;
			//
			DateTime dt;
			// array to generic list
			foreach ( x_lists.data_item xlist in x_results.data )
			{
				listsResults.DataItem lst = new listsResults.DataItem();
				//
				lst.id = xlist.id;
				lst.web_id = xlist.web_id;
				lst.name = xlist.name;
				DateTime.TryParse( xlist.date_created, out dt );
				lst.date_created = dt;
				//
				lst.email_type_option = xlist.email_type_option;
				lst.use_awesomebar = xlist.use_awesomebar;
				lst.default_from_name = xlist.default_from_name;
				lst.default_from_email = xlist.default_from_email;
				lst.default_subject = xlist.default_subject;
				lst.default_language = xlist.default_language;
				lst.list_rating = xlist.list_rating;
				//
				lst.stats = FormatStats( xlist.stats );
				lst.modules = null;
				//
				results.data.Add( lst );
			}
			return results;
		}
		//
		private listsResults.DataItem.statistics FormatStats( object x_stats )
		{
			double dbl;
			listsResults.DataItem.statistics stats = new listsResults.DataItem.statistics();

			if ( x_stats == null ) return stats;
			//
			IDictionary dict = x_stats as IDictionary;
			if ( dict["member_count"] != null )
			{ double.TryParse( dict["member_count"].ToString(), out dbl ); stats.member_count = dbl; }
			if ( dict["unsubscribe_count"] != null )
			{ double.TryParse( dict["unsubscribe_count"].ToString(), out dbl ); stats.unsubscribe_count = dbl; }
			if ( dict["cleaned_count"] != null )
			{ double.TryParse( dict["cleaned_count"].ToString(), out dbl ); stats.cleaned_count = dbl; }
			if ( dict["member_count_since_send"] != null )
			{ double.TryParse( dict["member_count_since_send"].ToString(), out dbl ); stats.member_count_since_send = dbl; }
			if ( dict["unsubscribe_count_since_send"] != null )
			{ double.TryParse( dict["unsubscribe_count_since_send"].ToString(), out dbl ); stats.unsubscribe_count_since_send = dbl; }
			if ( dict["cleaned_count_since_send"] != null )
			{ double.TryParse( dict["cleaned_count_since_send"].ToString(), out dbl ); stats.cleaned_count_since_send = dbl; }
			if ( dict["campaign_count"] != null )
			{ double.TryParse( dict["campaign_count"].ToString(), out dbl ); stats.campaign_count = dbl; }
			if ( dict["grouping_count"] != null )
			{ double.TryParse( dict["grouping_count"].ToString(), out dbl ); stats.grouping_count = dbl; }
			if ( dict["group_count"] != null )
			{ double.TryParse( dict["group_count"].ToString(), out dbl ); stats.group_count = dbl; }
			if ( dict["merge_var_count"] != null )
			{ double.TryParse( dict["merge_var_count"].ToString(), out dbl ); stats.merge_var_count = dbl; }
			if ( dict["avg_sub_rate"] != null )
			{ double.TryParse( dict["avg_sub_rate"].ToString(), out dbl ); stats.avg_sub_rate = dbl; }
			if ( dict["avg_unsub_rate"] != null )
			{ double.TryParse( dict["avg_unsub_rate"].ToString(), out dbl ); stats.avg_unsub_rate = dbl; }
			if ( dict["target_sub_rate"] != null )
			{ double.TryParse( dict["target_sub_rate"].ToString(), out dbl ); stats.target_sub_rate = dbl; }
			if ( dict["open_rate"] != null )
			{ double.TryParse( dict["open_rate"].ToString(), out dbl ); stats.open_rate = dbl; }
			if ( dict["click_rate"] != null )
			{ double.TryParse( dict["click_rate"].ToString(), out dbl ); stats.click_rate = dbl; }
			//
			return stats;
		}

		#endregion
	}
}
